`include "para_def.v"
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    10:57:21 07/10/2013 
// Design Name: 
// Module Name:    stage4 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module stage4(	 clk
					,rst_n
					
					,msg_end_3_4
					,ID_0
					,ID_1
					,ID_2
					,ID_3
					,ID_4
					,ID_5
					,ID_6
					,ID_7
					,ID_8
					,ID_9
					,ID_10
					,ID_11
					,ID_12
					,ID_13
					,ID_14
					,ID_15
					,ID_16
					,ID_17
					,ID_18
					,ID_19
					,ID_20
					,ID_21
					,ID_22
					,ID_23
					,ID_24
					,ID_25
					,ID_26
					,ID_27
					,ID_28
					,ID_29
					,ID_30
					,ID_31
					,ID_32
					,ID_33
					,ID_34
					,ID_35
					,ID_36
					,ID_37
					,ID_38
					,ID_39
					,ID_40
					,ID_41
					,ID_42
					,ID_43
					,ID_44
					,ID_45
					,ID_46
					,ID_47
					,ID_48
					,ID_49
					
					,valid
					,data_out
    );

input clk;
input rst_n;
input msg_end_3_4;
input [`ID_0_LEN*8 - 1  : 0]			ID_0;
input [`ID_1_LEN*8 - 1  : 0]			ID_1;
input [`ID_2_LEN*8 - 1  : 0]			ID_2;
input [`ID_3_LEN*8 - 1  : 0]			ID_3;
input [`ID_4_LEN*8 - 1  : 0]			ID_4;
input [`ID_5_LEN*8 - 1  : 0]			ID_5;
input [`ID_6_LEN*8 - 1  : 0]			ID_6;
input [`ID_7_LEN*8 - 1  : 0]			ID_7;
input [`ID_8_LEN*8 - 1  : 0]	 		ID_8;
input [`ID_9_LEN*8 - 1  : 0]			ID_9;
input [`ID_10_LEN*8 - 1  : 0]			ID_10;
input [`ID_11_LEN*8 - 1  : 0]			ID_11;
input [`ID_12_LEN*8 - 1  : 0]			ID_12;
input [`ID_13_LEN*8 - 1  : 0]			ID_13;
input [`ID_14_LEN*8 - 1  : 0]			ID_14;
input [`ID_15_LEN*8 - 1  : 0]			ID_15;
input [`ID_16_LEN*8 - 1  : 0]			ID_16;
input [`ID_17_LEN*8 - 1  : 0]			ID_17;
input [`ID_18_LEN*8 - 1  : 0]	 		ID_18;
input [`ID_19_LEN*8 - 1  : 0]			ID_19;
input [`ID_20_LEN*8 - 1  : 0]			ID_20;
input [`ID_21_LEN*8 - 1  : 0]			ID_21;
input [`ID_22_LEN*8 - 1  : 0]			ID_22;
input [`ID_23_LEN*8 - 1  : 0]			ID_23;
input [`ID_24_LEN*8 - 1  : 0]			ID_24;
input [`ID_25_LEN*8 - 1  : 0]			ID_25;
input [`ID_26_LEN*8 - 1  : 0]			ID_26;
input [`ID_27_LEN*8 - 1  : 0]			ID_27;
input [`ID_28_LEN*8 - 1  : 0]	 		ID_28;
input [`ID_29_LEN*8 - 1  : 0]			ID_29;
input [`ID_30_LEN*8 - 1  : 0]			ID_30;
input [`ID_31_LEN*8 - 1  : 0]			ID_31;
input [`ID_32_LEN*8 - 1  : 0]			ID_32;
input [`ID_33_LEN*8 - 1  : 0]			ID_33;
input [`ID_34_LEN*8 - 1  : 0]			ID_34;
input [`ID_35_LEN*8 - 1  : 0]			ID_35;
input [`ID_36_LEN*8 - 1  : 0]			ID_36;
input [`ID_37_LEN*8 - 1  : 0]			ID_37;
input [`ID_38_LEN*8 - 1  : 0]	 		ID_38;
input [`ID_39_LEN*8 - 1  : 0]			ID_39;
input [`ID_40_LEN*8 - 1  : 0]			ID_40;
input [`ID_41_LEN*8 - 1  : 0]			ID_41;
input [`ID_42_LEN*8 - 1  : 0]			ID_42;
input [`ID_43_LEN*8 - 1  : 0]			ID_43;
input [`ID_44_LEN*8 - 1  : 0]			ID_44;
input [`ID_45_LEN*8 - 1  : 0]			ID_45;
input [`ID_46_LEN*8 - 1  : 0]			ID_46;
input [`ID_47_LEN*8 - 1  : 0]			ID_47;
input [`ID_48_LEN*8 - 1  : 0]	 		ID_48;
input [`ID_49_LEN*8 - 1  : 0]			ID_49;

output valid;
output [63 : 0]							data_out;

reg [3 : 0]									field_counter;
reg											m_end;
reg [63 : 0]								ID_sel;

reg 											rd_en;
reg 											wr_en;
reg 											rd_en_0;
reg 											rd_en_1;
reg 											rd_en_2;
reg 											rd_en_3;

reg 											wr_en_0;
reg 											wr_en_1;
reg 											wr_en_2;
reg 											wr_en_3;

wire [63 : 0]								dout_0;
wire [63 : 0]								dout_1;
wire [63 : 0]								dout_2;
wire [63 : 0]								dout_3;
wire [63 : 0]								dout_6;
wire [63 : 0]								dout_7;
wire [63 : 0]								dout_8;
wire [63 : 0]								dout_9;
wire [63 : 0]								dout_10;

wire 											full;
wire 											full_0;
wire 											full_1;
wire 											full_2;
wire 											full_3;
wire 											full_6;
wire 											full_7;
wire 											full_8;
wire 											full_9;
wire 											full_10;

wire 											empty_0;
wire 											empty_1;
wire 											empty_2;
wire 											empty_3;
wire 											empty_6;
wire 											empty_7;
wire 											empty_8;
wire 											empty_9;
wire 											empty_10;
wire 											empty;

wire 											valid_0;
wire 											valid_1;
wire 											valid_2;
wire 											valid_3;
wire 											valid_6;
wire 											valid_7;
wire 											valid_8;
wire 											valid_9;
wire 											valid_10;

wire 											wr_ack_0;
wire 											wr_ack_1;
wire 											wr_ack_2;
wire 											wr_ack_3;
wire 											wr_ack_6;
wire 											wr_ack_7;
wire 											wr_ack_8;
wire 											wr_ack_9;
wire 											wr_ack_10;
wire 											wr_ack;


fifo_generator_v8_2_64bit ID_0_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({56'b0,ID_0}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_0),
										.full(full_0),
										.wr_ack(wr_ack_0),
										.empty(empty_0),
										.valid(valid_0)
);

fifo_generator_v8_2_64bit ID_1_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({56'b0,ID_1}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_1),
										.full(full_1),
										.wr_ack(wr_ack_1),
										.empty(empty_1),
										.valid(valid_1)
);

fifo_generator_v8_2_64bit ID_2_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({56'b0,ID_2}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_2),
										.full(full_2),
										.wr_ack(wr_ack_2),
										.empty(empty_2),
										.valid(valid_2)
);

fifo_generator_v8_2_64bit ID_3_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({56'b0,ID_3}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_3),
										.full(full_3),
										.wr_ack(wr_ack_3),
										.empty(empty_3),
										.valid(valid_3)
);

fifo_generator_v8_2_64bit ID_6_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({24'b0,ID_6}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_6),
										.full(full_6),
										.wr_ack(wr_ack_6),
										.empty(empty_6),
										.valid(valid_6)
);

fifo_generator_v8_2_64bit ID_7_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({56'b0,ID_7}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_7),
										.full(full_7),
										.wr_ack(wr_ack_7),
										.empty(empty_7),
										.valid(valid_7)
);

fifo_generator_v8_2_64bit ID_8_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({48'b0,ID_8}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_8),
										.full(full_8),
										.wr_ack(wr_ack_8),
										.empty(empty_8),
										.valid(valid_8)
);

fifo_generator_v8_2_64bit ID_9_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({48'b0,ID_9}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_9),
										.full(full_9),
										.wr_ack(wr_ack_9),
										.empty(empty_9),
										.valid(valid_9)
);

fifo_generator_v8_2_64bit ID_10_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din({56'b0,ID_10}),
										.wr_en(msg_end_3_4),
										.rd_en(m_end),
										.dout(dout_10),
										.full(full_10),
										.wr_ack(wr_ack_10),
										.empty(empty_10),
										.valid(valid_10)
);

fifo_generator_v8_2_64bit output_FIFO(
										.clk(clk),
										.rst(~rst_n),
										.din(ID_sel),
										.wr_en(wr_en),
										.rd_en(valid),
										.dout(data_out),
										.full(full),
										.wr_ack(wr_ack),
										.empty(empty),
										.valid(valid)
);


always@(posedge clk) begin
	case (field_counter)
	0:
		ID_sel=dout_0;
	1:
		if (		dout_0==`a_ASCII 
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`Y_ASCII
					|| dout_0==`H_ASCII
					|| dout_0==`C_ASCII
					|| dout_0==`f_ASCII		) ID_sel=dout_1;
	2:
		if (		dout_0==`a_ASCII
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`Y_ASCII
					|| dout_0==`H_ASCII
					|| dout_0==`C_ASCII
					|| dout_0==`f_ASCII		) ID_sel=dout_2;
	3:
		if (		dout_0==`a_ASCII			
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`Y_ASCII
					|| dout_0==`H_ASCII
					|| dout_0==`C_ASCII
					|| dout_0==`f_ASCII		) ID_sel=dout_3;
	4:
		if (		dout_0==`a_ASCII			
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`f_ASCII		) ID_sel=dout_6;
	5:
		if (		dout_0==`a_ASCII			
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`f_ASCII		) ID_sel=dout_7;
	6:
		if (		dout_0==`a_ASCII			
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`f_ASCII		) ID_sel=dout_8;
	7:
		if (		dout_0==`a_ASCII			
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`f_ASCII		) ID_sel=dout_9;
	8:
		if (		dout_0==`a_ASCII			
					|| dout_0==`k_ASCII		
					|| dout_0==`d_ASCII		
					|| dout_0==`f_ASCII		) ID_sel=dout_10;
	default:
		ID_sel=dout_0;
	endcase
end

always@(posedge clk or negedge rst_n)
begin
	if (~rst_n)
		field_counter<=0;
	else begin
		if (valid_0) begin
			if (m_end) field_counter<=0;
			else field_counter<=field_counter+1;
		end
		else
			field_counter<=0;
	end
end

always@(posedge clk or negedge rst_n)
begin
	if (~rst_n)
		m_end<=0;
	else begin
		if (		(dout_0==`a_ASCII && field_counter==7 && m_end==0 )
				 ||(dout_0==`d_ASCII && field_counter==7 && m_end==0 )
				 ||(dout_0==`k_ASCII && field_counter==7 && m_end==0 )
				 ||(dout_0==`f_ASCII && field_counter==7 && m_end==0 )
				 ||(dout_0==`Y_ASCII && field_counter==2 && m_end==0 )
				 ||(dout_0==`H_ASCII && field_counter==2 && m_end==0 )
				 ||(dout_0==`C_ASCII && field_counter==2 && m_end==0 )	) m_end<=1;
		else m_end<=0;
	end
end 


always@(posedge clk or negedge rst_n)
begin
	if (~rst_n)
		wr_en<=0;
	else begin
		wr_en<=valid_0;
	end
end

endmodule
